package com.totoro.tyrank.listener;

import com.totoro.tyrank.TyRank;
import com.totoro.tyrank.data.PlayerData;
import com.totoro.tyrank.data.RankingData;
import com.totoro.tyrank.manager.AttributeManager;
import com.totoro.tyrank.utils.DateUtil;
import com.totoro.tyrank.utils.ListUtil;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JoinLeaveListener implements Listener {

    @EventHandler
    public void onJoin (PlayerJoinEvent playerJoinEvent) {
        Player player = playerJoinEvent.getPlayer();
        // 加载属性
        TyRank.getAttributeManager().loadAttribute(player);
        // 上线提示
        doOnlineTips(player);
    }

    @EventHandler
    public void onLeave (PlayerQuitEvent playerQuitEvent) {
        Player player = playerQuitEvent.getPlayer();
        // 移除属性
        TyRank.getAttributeManager().deleteAttribute(player);
    }


    /**
     * @author totoro
     * @description 上线提示
     * @date  19:54
     * @param [player]
     * @return void
     **/
    public void doOnlineTips(Player player) {
        Bukkit.getScheduler().runTaskAsynchronously(TyRank.getInstance(), () -> {
            // 上线提示
            // 排行属性提示
            if(TyRank.getConfigManager().getConfigData().getOnlineTipsEnable().getAttribute()) {
                // 获取规则：先获取所有正在进行的排行榜
                List<String> attributeEffectList = getAllEffectAttrStrList(player);
                // 没有一点点属性
                if(ListUtil.isBlank(attributeEffectList)) {
                    player.sendMessage(TyRank.getConfigManager().getConfigData().getPrefix() +
                            TyRank.getLanguageManager().getLanguageData().getMsg().getNotAttributeOnlineTip());
                } else {
                    // 有属性，解析并合并所有属性
                    List<String> mergeAttribute = ListUtil.mergeStats(attributeEffectList);
                    String attributeOnlineTip = TyRank.getLanguageManager().getLanguageData().getMsg().getAttributeOnlineTip();
                    // 替换 <attribute> 占位符
                    attributeOnlineTip = attributeOnlineTip.replace("<attribute>", ListUtil.formatString(mergeAttribute, "\n"));
                    player.sendMessage(attributeOnlineTip);
                }
            }


            // 排行奖励提示
            if(TyRank.getConfigManager().getConfigData().getOnlineTipsEnable().getReward()) {
                Map<String, String> rewardReceiveMap = getEffectRankNameRewardMap(player);
                // 没有任何奖励可领取
                if(rewardReceiveMap.isEmpty()) {
                    player.sendMessage(TyRank.getConfigManager().getConfigData().getPrefix() +
                            TyRank.getLanguageManager().getLanguageData().getMsg().getNotRewardOnlineTip());
                } else {
                    // 组装数据
                    List<String> rankNameReceiveStrList = new ArrayList<>();
                    rewardReceiveMap.forEach((rankName, rankingText) -> {
                        rankNameReceiveStrList.add("$1" + rankName + "$2" + rankingText + "$3");
                    });
                    String regex = "(.*?)<rankName>(.*?)<ranking>(.*)";
                    String rewardOnlineTip = TyRank.getLanguageManager().getLanguageData().getMsg().getRewardOnlineTip();
                    rewardOnlineTip = rewardOnlineTip.replaceAll(regex, ListUtil.formatString(rankNameReceiveStrList, "\n"));
                    player.sendMessage(rewardOnlineTip);
                }
            }
                });
    }

    /**
     * @author totoro
     * @description 获取玩家所有生效的奖励
     * @date  19:54
     * @param [player]
     * @return java.util.Map<java.lang.String,java.lang.String>
     **/
    @NotNull
    private Map<String, String> getEffectRankNameRewardMap(Player player) {
        Map<String, String> rewardReceiveMap = new HashMap<>();
        Map<String, RankingData> currentRankDataMap = TyRank.getRankingManager().getRankDataMap();
        currentRankDataMap.forEach((rankId, rankingData) -> {
            // 排行榜是否闭榜，必须闭榜
            if(DateUtil.isCurrentTimeAfter(rankingData.getEndTime())){
                PlayerData playerData = TyRank.getPlayerDataManager().getPlayerDataByRankId(player, rankId);
                if (null != playerData && null != playerData.getRanking() && playerData.getRanking() > 0) {
                    // 该玩家在排行榜有名次，而且未领取过，然后该名次的奖励也是有的
                    if (!playerData.getRewardReceive()) {
                        RankingData.RankingReceive receive = TyRank.getRankingReceiveManager().getReceive(rankId, playerData.getRanking());
                        if (null != receive) {
                            RankingData.RankingReceive.Reward reward = receive.getReward();
                            if (null != reward) {
                                rewardReceiveMap.put(rankingData.getRankName(), receive.getRankingText());
                            }
                        }
                    }
                }
            }
        });
        return rewardReceiveMap;
    }

    /**
     * @author totoro
     * @description 获取玩家所有生效的属性
     * @date  19:54
     * @param [player]
     * @return java.util.List<java.lang.String>
     **/
    @NotNull
    private List<String> getAllEffectAttrStrList(Player player) {
        Map<String, RankingData> currentRankDataMap = TyRank.getRankingManager().getCurrentRankDataMap();
        List<String> attributeEffectList = new ArrayList<>();
        currentRankDataMap.forEach((rankId, rankingData) -> {
            PlayerData playerData = TyRank.getPlayerDataManager().getPlayerDataByRankId(player, rankId);
            if(null != playerData && null != playerData.getRanking() && playerData.getRanking() > 0) {
                RankingData.RankingReceive receive = TyRank.getRankingReceiveManager().getReceive(rankId, playerData.getRanking());
                if(null != receive) {
                    RankingData.RankingReceive.Attribute attribute = receive.getAttribute();
                    if (null != attribute) {
                        attributeEffectList.addAll(attribute.getGiveAttribute());
                    }
                }
            }
        });
        return attributeEffectList;
    }

}
